package com.mvvm.start.common.network

import AppConfig.baseUrl
import AppConfig.baseUrlTest
import com.lubansoft.lib_basic.network.converter.MVVMStartGsonConverterFactory
import com.mvvm.start.base.BaseApplication
import com.mvvm.start.base.utils.CommonUtils
import com.mvvm.start.common.CommonApplication
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.io.File
import java.io.IOException
import java.net.Proxy.NO_PROXY
import java.util.concurrent.TimeUnit

/**
 * @author Lmy
 * @功能: RetrofitHelp初始化的帮助类
 * @Creat 2020/5/21 10:03
 * @Compony 永远相信美好的事物即将发生
 */
object RetrofitHelp {
    private val loggingInterceptor by lazy {
        HttpLoggingInterceptor()
    }
    private val client by lazy {
        //设置Http缓存
        var cache: Cache? = Cache(
            File(BaseApplication.context.cacheDir, "HttpCache"),
            1024 * 1024 * 10
        )
//        okhttp设置部分，此处还可再设置网络参数
        OkHttpClient.Builder()
            .apply {
                connectTimeout(10, TimeUnit.SECONDS)
//                cache(cache)
                callTimeout(60, TimeUnit.SECONDS)
                readTimeout(10, TimeUnit.SECONDS)
                addNetworkInterceptor(CacheInterceptor())
                writeTimeout(10, TimeUnit.SECONDS)
                if (true) {
                    //注意这里下载文件时需要关闭
                    //不然会把文件全部加载进内存中
                    addInterceptor(loggingInterceptor)
                }
                proxy(NO_PROXY)//禁止使用代理 防止恶意抓包
            }.build()
    }

    init {
        //初始化loggingInterceptor 日志拦截器  和okhttp3失败重连的配置；
        loggingInterceptor.apply {
            level = HttpLoggingInterceptor.Level.BODY
        }
    }

    private val retrofit = Retrofit.Builder()
        .baseUrl(if (BaseApplication.isTestUrl) baseUrlTest else baseUrl)
        .client(client)
        .addCallAdapterFactory(CoroutineCallAdapterFactory())
//        .addConverterFactory(GsonConverterFactory.create())
        .addConverterFactory(MVVMStartGsonConverterFactory.create())
        .build()

    /**
     * 这里使用泛型来创建ServiceClass
     */
    fun <T> creat(service: Class<T>): T = retrofit.create(service)

    /**
     * 这里使用了泛型实例化 主要的区别在于调用方式
     *  ServiceCreator.creat(PalceService::class.java)
     *  ServiceCreator.creat<PalceService>()
     */
    inline fun <reified T> creat(): T = creat(T::class.java)

    /**
     * 为okhttp添加缓存，这里是考虑到服务器不支持缓存时，从而让okhttp支持缓存
     */
    private class CacheInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            // 有网络时 设置缓存超时时间1个小时
            val maxAge = 60 * 60
            // 无网络时，设置超时为1天
            val maxStale = 60 * 60 * 24
            var request = chain.request()
            val jwtToken = "${CommonUtils.getToken()}"
            val channelName = CommonApplication.mCommonApplication.getChannelName()
            request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK)
                .addHeader("token", jwtToken)
                .addHeader("versionCode", CommonUtils.getAppVersionCode().toString())
                .addHeader("versionName", CommonUtils.getAppVersionName())
                .addHeader("channelNumber", channelName)
                .addHeader("androidID", CommonUtils.getAndroidId(BaseApplication.context))
                .build()
//            request = if (NetWorkUtils.isNetworkAvailable(App.context)) {
//                //有网络时只从网络获取
//                request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK)
//                    .addHeader("token", jwtToken)
//                    .build()
//            } else {
//                //无网络时只从缓存中读取
//                request.newBuilder().cacheControl(CacheControl.FORCE_CACHE)
//                    .addHeader("token", jwtToken)
//                    .build()
//            }
            var response = chain.proceed(request)
            response = response.newBuilder()
                .removeHeader("Pragma")
                .header("Cache-Control", "public, max-age=$maxAge")
                .build()
//            response = if (NetWorkUtils.isNetworkAvailable(App.context)) {
//                response.newBuilder()
//                    .removeHeader("Pragma")
//                    .header("Cache-Control", "public, max-age=$maxAge")
//                    .build()
//            } else {
//                response.newBuilder()
//                    .removeHeader("Pragma")
//                    .header("Cache-Control", "public, only-if-cached, max-stale=$maxStale")
//                    .build()
//            }
            return response
        }
    }
}
